package utils

import (
	"errors"
	"fmt"
	"time"

	"github.com/golang-jwt/jwt/v4"
)

/*
 +----------------------------------------------------------------------
 + Title        : token
 + Author       : huwl
 + Version      : 1.0.0
 + Initial-Time : 2018-01-06
 + Last-time    : 这个文件最后修改的时间 + 修改人的名称
 + Desc         : golang-jwt
 +----------------------------------------------------------------------
*/

/**
 * 生成token
 *
 * @param string uid ---------------------------必传
 * @return string, error
 */
func GenerateToken(secretKey string, iat, seconds, uid int64) (string, error) {
	if uid <= 0 {
		return "", errors.New("用户ID不能为空")
	}

	claims := make(jwt.MapClaims)
	claims["exp"] = iat + seconds
	claims["iat"] = iat
	claims["uid"] = uid
	token := jwt.New(jwt.SigningMethodHS256)
	token.Claims = claims
	return token.SignedString([]byte(secretKey))
}

/**
 * 解析token
 *
 * @param string token ---------------------------必传
 * @return int64, error
 */
func ParseToken(token, secret string) (int64, error) {
	if token == "" {
		return 0, errors.New("token不能为空")
	}

	parseToken, err := jwt.Parse(token, func(t *jwt.Token) (interface{}, error) {
		if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("Unexpected signing method: %v", t.Header["alg"])
		}

		return []byte(secret), nil
	})

	if err != nil {
		return 0, err
	}

	if claims, ok := parseToken.Claims.(jwt.MapClaims); ok && parseToken.Valid {
		val := claims["uid"].(float64)
		exp := int64(claims["exp"].(float64))
		if exp <= time.Now().Unix() {
			return 0, errors.New("token已过期")
		}

		return int64(val), nil
	}

	return 0, errors.New("token 错误")
}
